﻿using Com.Lancetinc.Evs.Helpers;
using System.Text;

namespace Com.Lancetinc.Evs.Cameras
{
    public enum CameraPropModifyFlag
    {
        /// <summary>
        /// 不可修改
        /// </summary>
        Disable = 0,

        /// <summary>
        /// 自动 不可修改
        /// </summary>
        Auto = 1,

        /// <summary>
        /// 手动可以修改
        /// </summary>
        Manual = 2,

        /// <summary>
        /// 自动和手动
        /// </summary>
        AutoAndManual = 3
    }

    public enum CameraPropAutoFlag
    {
        None = 0x0000,
        Auto = 0x0001,
        Manual = 0x0002
    };

    public enum CameraPropCategory
    {
        ProcAmp = 1,
        Control = 2,
        WhiteBalance = 3
    }

    public enum CameraPropProcAmp
    {
        Brightness = 0,
        Contrast = 1,
        Hue = 2,
        Saturation = 3,
        Sharpness = 4,
        Gamma = 5,
        ColorEnable = 6,
        WhiteBalance = 7,
        BacklightCompensation = 8,
        Gain = 9,
        PowerLine = 13
    }

    public enum CameraPropControl
    {
        Pan = 0,
        Tilt = (Pan + 1),
        Roll = (Tilt + 1),
        Zoom = (Roll + 1),
        Exposure = (Zoom + 1),
        Iris = (Exposure + 1),
        Focus = (Iris + 1),
        LowlightCompensation = 19
    };

    public enum CameraPropWhiteBalance
    {
        R = 0x8270,
        RGain = 0x8271,
        G = 0x8272,
        GGain = 0x8273,
        B = 0x8274,
        BGain = 0x8275
    };

    public class CameraProp
    {
        public readonly int PropId;
        public readonly string Name;
        public readonly CameraPropCategory Category;
        public int Min = 0;
        public int Max = 0;
        public int Step = 0;
        public int DefaultValue = 0;
        public CameraPropModifyFlag ModifyFlag = 0;
        public int Value = 0;
        public CameraPropAutoFlag AutoFlag = CameraPropAutoFlag.None;

        public void SafeSetValue(int value)
        {
            if (value > Max)
            {
                this.Value = Max;
            }
            else if (value < Min)
            {
                this.Value = Min;
            }
            else
            {
                this.Value = value;
            }
        }

        public CameraProp(CameraPropCategory category, int propId, string name)
        {
            this.Category = category;
            this.PropId = propId;
            this.Name = name;
        }

        public CameraProp(CameraProp other) : this(other.Category, other.PropId, other.Name)
        {
            this.Min = other.Min;
            this.Max = other.Max;
            this.Step = other.Step;
            this.DefaultValue = other.DefaultValue;
            this.ModifyFlag = other.ModifyFlag;
            this.Value = other.Value;
            this.AutoFlag = other.AutoFlag;
        }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.Append("Name=").Append(this.Name);
            sb.Append(",Category=").Append(this.Category);
            sb.Append(",PropId=").Append(this.PropId);
            sb.Append(",Min=").Append(this.Min);
            sb.Append(",Max=").Append(this.Max);
            sb.Append(",Step=").Append(this.Step);
            sb.Append(",DefaultValue=").Append(this.DefaultValue);
            sb.Append(",ModifyFlag=").Append(this.ModifyFlag);
            sb.Append(",AutoFlag=").Append(this.AutoFlag);
            sb.Append(",Value=").Append(this.Value);
            return sb.ToString();
        }

        public string ToShortString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Name=").Append(this.Name);
            sb.Append(",Category=").Append(this.Category);
            sb.Append(",PropId=").Append(this.PropId);
            sb.Append(",Value=").Append(this.Value);
            return sb.ToString();
        }
    }

    public static class CameraProps
    {
        public static CameraProp[] ALL = new CameraProp[] {
            CreateProp(CameraPropProcAmp.Brightness),
            CreateProp(CameraPropProcAmp.Contrast),
            CreateProp(CameraPropProcAmp.Hue),
            CreateProp(CameraPropProcAmp.Saturation),
            CreateProp(CameraPropProcAmp.Sharpness),
            CreateProp(CameraPropProcAmp.Gamma),
            CreateProp(CameraPropProcAmp.Brightness),
            CreateProp(CameraPropProcAmp.WhiteBalance),
            CreateProp(CameraPropProcAmp.BacklightCompensation),
            CreateProp(CameraPropProcAmp.PowerLine),

            CreateProp(CameraPropControl.Exposure),
            CreateProp(CameraPropControl.LowlightCompensation),

            CreateProp(CameraPropWhiteBalance.R),
            CreateProp(CameraPropWhiteBalance.RGain),
            CreateProp(CameraPropWhiteBalance.G),
            CreateProp(CameraPropWhiteBalance.GGain),
            CreateProp(CameraPropWhiteBalance.B),
            CreateProp(CameraPropWhiteBalance.BGain)
        };

        private static CameraProp CreateProp(CameraPropProcAmp propId)
        {
            return new CameraProp(CameraPropCategory.ProcAmp, (int)propId, I18nHelper.Default.GetMessage("CameraPropProcAmp." + propId.ToString()));
        }

        private static CameraProp CreateProp(CameraPropControl propId)
        {
            return new CameraProp(CameraPropCategory.Control, (int)propId, I18nHelper.Default.GetMessage("CameraPropControl." + propId.ToString()));
        }

        private static CameraProp CreateProp(CameraPropWhiteBalance propId)
        {
            var prop = new CameraProp(CameraPropCategory.WhiteBalance, (int)propId, propId.ToString())
            {
                ModifyFlag = CameraPropModifyFlag.Manual,
                AutoFlag = CameraPropAutoFlag.Manual
            };
            if (propId == CameraPropWhiteBalance.R || propId == CameraPropWhiteBalance.G || propId == CameraPropWhiteBalance.B)
            {
                prop.Max = 255;
            }
            else
            {
                prop.Max = 7;
            }
            return prop;
        }
    }
}
